﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;

namespace AtomPuzzleSolver.Model
{
    [Serializable]
    public class HexagonalGrid
    {
        private int _Width;
        private int _Height;

        public int Width
        {
            get { return _Width; }
        }
        public int Height
        {
            get { return _Height; }
        }

        public HexagonalCell[,] _innerArray;

        public HexagonalGrid(int width, int height)
        {
            _Width = width;
            _Height = height;

            _innerArray = new HexagonalCell[width, height];
            InitializeArray();
        }

        private void InitializeArray()
        {
            for (int i = 0; i < Width; i++)
            {
                for (int j = 0; j < Height; j++)
                {
                    _innerArray[i, j] = new HexagonalCell(i, j);
                }
            }
        }

        public IList<HexagonalCell> CellsFlat
        {
            get
            {
                var flats = new List<HexagonalCell>();
                foreach (var i in _innerArray)
                {
                    flats.Add(i);
                }

                return flats;
            }
        }

        public HexagonalCell this[int i, int j]
        {
            get
            {
                return _innerArray[i, j];
            }
            set
            {
                _innerArray[i, j] = value;
            }
        }

        public bool Insert(Molecule molecule, int originX, int originY)
        {
            foreach (var atom in molecule.Atoms)
            {
                int x = originX;
                int y = originY;
                y += (x & 1) * (atom.Bonding.X & 1); //add one if both x coords are odd
                x += atom.Bonding.X;
                y += atom.Bonding.Y;

                if (_innerArray.IsInBound(x, y) && _innerArray[x, y].State == CellState.Active)
                {
                    _innerArray[x, y].Color = molecule.Color;
                    _innerArray[x, y].State = CellState.Inactive;
                }
                else
                {
                    Remove(molecule);
                    return false;
                }
            }
            return true;
        }

        public void Remove(Molecule molecule, int originX, int originY)
        {
            foreach (var atom in molecule.Atoms)
            {
                int x = originX;
                int y = originY;
                y += (x & 1) * (atom.Bonding.X & 1); //add one if both x coords are odd
                x += atom.Bonding.X;
                y += atom.Bonding.Y;

                //_innerArray[x, y].Color = Colo;
                _innerArray[x, y].State = CellState.Active;
            }
        }

        public void Remove(Molecule molecule)
        {
            foreach (var cell in CellsFlat.Where(c => c.Color == molecule.Color))
            {
                cell.State = CellState.Active;
            }
        }

        public HexagonalGrid Clone()
        {
            HexagonalGrid newGrid = new HexagonalGrid(_Width, _Height);

            for (int i = 0; i < _Width; i++)
            {
                for (int j = 0; j < _Height; j++)
                {
                    var oldCell = this[i, j];
                    newGrid[i,j] = new HexagonalCell(oldCell.Coordinates.X, oldCell.Coordinates.Y, oldCell.State, oldCell.Color);
                }
            }

            return newGrid;
        }

    }
}
